/*
* Copyright (c) 2025 Shenzhen Kaihong Digital Industry Development Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class XVec4 {
    constructor(x = 0, y = 0, z = 0, w = 1) {
        this.vec = [x, y, z, w];
    }
    set(x, y, z, w = 1) {
        this.vec = [x, y, z, w];
        return this;
    }
    mult(mat4) {
        let ox = this.vec[0] * mat4.mat[0][0] + this.vec[1] * mat4.mat[1][0] + this.vec[2] * mat4.mat[2][0] + this.vec[3] * mat4.mat[3][0];
        let oy = this.vec[0] * mat4.mat[0][1] + this.vec[1] * mat4.mat[1][1] + this.vec[2] * mat4.mat[2][1] + this.vec[3] * mat4.mat[3][1];
        let oz = this.vec[0] * mat4.mat[0][2] + this.vec[1] * mat4.mat[1][2] + this.vec[2] * mat4.mat[2][2] + this.vec[3] * mat4.mat[3][2];
        let ow = this.vec[0] * mat4.mat[0][3] + this.vec[1] * mat4.mat[1][3] + this.vec[2] * mat4.mat[2][3] + this.vec[3] * mat4.mat[3][3];
        this.vec = [ox, oy, oz, ow];
        return this;
    }
    transform(mat4) {
        const { Scr } = require("../XDefine");
        const { X3DFast } = require("./X2DInterface");
        this.mult(mat4);
        this.mult(X3DFast.umat);

        return [(this.vec[0] / this.vec[3] + 1) * Scr.logicw / 2, (1 - this.vec[1] / this.vec[3]) * Scr.logich / 2];
    }
    normalize() {
        const len = Math.sqrt(this.vec[0] * this.vec[0] + this.vec[1] * this.vec[1] + this.vec[2] * this.vec[2] + this.vec[3] * this.vec[3]);
        this.vec[0] /= len;
        this.vec[1] /= len;
        this.vec[2] /= len;
        this.vec[3] /= len;
        return this;
    }
    clone() {
        return new XVec4(this.vec[0], this.vec[1], this.vec[2], this.vec[3]);
    }
    makeRotateMat(theta) {//绕此向量旋转的矩阵
        const { XMat4 } = require("./XMat4");
        const mat = new XMat4();
        let a = 1 - Math.cos(theta);
        this.normalize();
        let Ux = this.vec[0], Uy = this.vec[1], Uz = this.vec[2];
        mat.mat = [
            [Math.cos(theta) + Ux * Ux * a, Ux * Uy * a - Uz * Math.sin(theta), Ux * Uz * a + Uy * Math.sin(theta), 0],
            [Uy * Ux * a + Uz * Math.sin(theta), Math.cos(theta) + Uy * Uy * a, Uy * Uz * a - Ux * Math.sin(theta), 0],
            [Uz * Ux * a - Uy * Math.sin(theta), Uz * Uy * a + Ux * Math.sin(theta), Math.cos(theta) + Uz * Uz * a, 0],
            [0, 0, 0, 1]
        ];
        return mat;
    }
}

module.exports = {
    XVec4
};